<template>
  <component :is="RemoteChild" v-if="showRemote" :key="componentKey" />
</template>

<script setup>
import {defineAsyncComponent, ref, computed, watch} from "vue";
import * as Vue from "vue";
import {loadModule} from "vue3-sfc-loader";

const props = defineProps({
  // 初始是否显示组件
  show: {
    type: Boolean,
    default: false
  },
  // SFC 文件内容
  sfcContent: {
    type: String,
    required: true
  }
});

const emit = defineEmits(['update:show']);

const showRemote = ref(props.show);
const componentKey = ref(0); // 用于强制重新渲染的key

// 监听父组件的show属性变化
watch(() => props.show, (newVal) => {
  showRemote.value = newVal;
});
const transform=() => {
  componentKey.value++;
}
// 显示/隐藏组件
const toggle= (show) => {
  showRemote.value = show !== undefined ? show : !showRemote.value;
  emit('update:show', showRemote.value);
}
// 暴露给父组件的方法
defineExpose({
  transform,toggle
});

// 公共项目路径
const baseProjectPath = window.location.origin;
// 默认src路径别名
const srcAlias = `${baseProjectPath}/src`;

// 特殊组件定义
const specialComponentsMap = {
  'IframeToggle': '<template><div class="iframe-toggle-placeholder"></div></template><script>export default { name: "IframeToggle" }<\/script>'
};

// 检查URL是否已包含扩展名
function ensureExtension(url, ext = '.vue') {
  // 如果URL已经以扩展名结尾，则不添加
  if (url.endsWith(ext) || url.includes(ext + '?')) {
    return url;
  }

  // 检查是否包含查询参数
  const queryIndex = url.indexOf('?');
  if (queryIndex > -1) {
    // 在查询参数前添加扩展名
    return url.slice(0, queryIndex) + ext + url.slice(queryIndex);
  }

  // 直接添加扩展名
  return url + ext;
}

const options = {
  pathResolve({refPath, relPath}) {
    // 如果是动态组件文件名，直接返回
    if (relPath.includes('dynamic-component-')) {
      return relPath;
    }

    // 处理@/开头的路径 (Vue项目中通常指向src目录)
    if (relPath.startsWith('@/')) {
      return `${srcAlias}${relPath.substring(1)}`;
    }

    // 处理./开头的相对路径
    if (relPath.startsWith('./') || relPath.startsWith('../')) {
      // 基于refPath的目录来构建相对路径
      let basePath = refPath ? refPath.substring(0, refPath.lastIndexOf('/')) : baseProjectPath;

      // 规范化路径，处理../情况
      const parts = relPath.split('/');
      const resultParts = [];

      for (const part of parts) {
        if (part === '.' || part === '') continue;
        if (part === '..') {
          resultParts.pop(); // 移除上一个路径部分
          basePath = basePath.substring(0, basePath.lastIndexOf('/'));
        } else {
          resultParts.push(part);
        }
      }

      return `${basePath}/${resultParts.join('/')}`;
    }

    // 处理直接导入的node_modules模块
    if (relPath[0] !== '/' && !relPath.includes(':')) {
      return relPath;
    }

    // 处理绝对路径
    if (relPath.startsWith('/')) {
      return `${baseProjectPath}${relPath}`;
    }

    // 默认情况下使用URL构造
    try {
      return String(new URL(relPath, refPath || baseProjectPath));
    } catch (e) {
      console.warn('路径解析失败:', e);
      return relPath;
    }
  },
  moduleCache: {
    vue: Vue,
  },
  async getFile(url) {
    // 对于主要动态组件，返回传入的内容
    if (url.includes('dynamic-component-')) {
      return props.sfcContent;
    }

    // 检查是否是预定义的特殊组件
    for (const [componentName, content] of Object.entries(specialComponentsMap)) {
      if (url.includes(componentName)) {
        console.log(`使用预定义组件: ${componentName}`);
        return content;
      }
    }

    console.log('尝试加载模块:', url);

    // 确保URL具有.vue扩展名
    const fetchUrl = ensureExtension(url);

    try {
      // 尝试获取项目中的实际文件
      const response = await fetch(fetchUrl);
      if (!response.ok) {
        throw new Error(`文件加载失败: ${fetchUrl}, 状态: ${response.status}`);
      }
      const content = await response.text();

      // 检查内容是否看起来像Vue SFC（包含template, script或style标签）
      if (!content.includes('<template') &&
          !content.includes('<script') &&
          !content.includes('<style')) {
        throw new Error('获取的内容不是有效的Vue单文件组件');
      }

      return content;
    } catch (err) {
      console.warn('模块加载失败:', err);

      // 为路径中包含的组件名创建默认实现
      const pathParts = url.split('/');
      const componentName = pathParts[pathParts.length - 1] || pathParts[pathParts.length - 2] || 'UnknownComponent';

      console.log(`为组件 ${componentName} 创建空实现`);

      // 返回带有组件名的空组件
      return '<template><div class="dynamic-placeholder ' + componentName.toLowerCase() + '-placeholder"></div></template><script>export default {name:"' + componentName + '"}<\/script><style scoped>.dynamic-placeholder{display:none;}</style>';
    }
  },
  addStyle(textContent) {
    const style = Object.assign(document.createElement("style"), {
      textContent,
    });
    document.head.appendChild(style);
  },
};

// 使用计算属性动态创建组件
const RemoteChild = computed(() => {
  // 创建唯一的文件名避免缓存
  const fileName = `dynamic-component-${componentKey.value}.vue`;

  return defineAsyncComponent(() =>
    loadModule(fileName, options)
  );
});
</script>
